/*
 *    wmain.cpp (WordTrending)
 *    Asif Shahidullah
 *
 *    Implements the main algorithm for the WordTrending
 *    program.
 *
 */

#include "array_sort.hpp"
#include "binary_tree.hpp"
#include "list_ranker.h"
using namespace ece::tree;
using namespace ece::sort;

#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
   ifstream startFile;
   ifstream endFile;
   ofstream rankOutputFile;

   binary_tree<string> startFile_tree;
   binary_tree<string> endFile_tree;

   binary_tree<string>::tree_data* startFile_array;
   binary_tree<string>::tree_data* endFile_array;

   array_sort<binary_tree<string>::tree_data> sorter;

   unsigned int i;
   string curr;

   if (argc != 4) {
      cerr << "Usage: trending startFile endFile rankOutputFile" 
         << endl;
      return -1;
   }

   // Get words from startFile
   startFile.open (argv[1], ios::in);
   if (!startFile.good()) {
      cerr << "Failed to open startFile" << endl;
      return -1;
   }
   while (startFile >> curr) {
      for (i = 0; i < curr.size(); i++)
         curr[i] = (char) tolower (curr[i]);
      startFile_tree.insert (curr);
   }

   // Get words from endFile
   endFile.open (argv[2], ios::in);
   if (!endFile.good()) {
      cerr << "Failed to open endFile" << endl;
      return -1;
   }
   while (endFile >> curr) {
      for (i = 0; i < curr.size(); i++)
         curr[i] = (char) tolower (curr[i]);
      endFile_tree.insert (curr);
   }

   startFile.close();
   endFile.close();

   /* Ensure that both lists were populated with words, or 
      exit with a message */
   if (startFile_tree.size() == 0 || endFile_tree.size() == 0) {
      cerr << "Empty file detected. Both files need to be "
         << "populated in order to calculate trending statistics."
         << endl;
      return -1;
   }

   // Convert words from tree into array
   startFile_array = new 
      binary_tree<string>::tree_data[startFile_tree.size()];
   endFile_array = new
      binary_tree<string>::tree_data[endFile_tree.size()];

   startFile_tree.to_array (startFile_array);
   endFile_tree.to_array (endFile_array);

   // Sort both arrays
   sorter.mergesort (startFile_array, startFile_tree.size());
   sorter.mergesort (endFile_array, endFile_tree.size());

   // Get rank of word in each list
   rank_list (startFile_array, startFile_tree.size());
   rank_list (endFile_array, endFile_tree.size());

   /* Output the endFile word list along with change in ranks
      from startFile */
   rankOutputFile.open (argv[3], ios::out);
   if (!rankOutputFile.good()) {
      cerr << "Failed to open rankOutputFile for writing" << endl;
      return -1;
   }

   unsigned int end = endFile_tree.size(), jend = startFile_tree.size();
   for (i = 0; i < end; i++) {
      rankOutputFile << ((endFile_array[i].tie == true)? "T":"")
         << endFile_array[i].rank << ": "
         << endFile_array[i].data;

      // Find word in startFile_array
      bool found = false;
      unsigned int j;
      for (j = 0; j < jend; j++) {
         if (startFile_array[j].data == endFile_array[i].data) {
            found = true;
            break;
         }
      }

      if (found == true) {
         int delta_rank = startFile_array[j].rank - endFile_array[i].rank;
         rankOutputFile << ((delta_rank < 0)? " (":" (+") << delta_rank << ")"
            << endl;
      } else
         rankOutputFile << " (new)" << endl;
   }

   rankOutputFile.close();
   return 0;
}
